//
//  SpellMethods.m
//  This file is part of D&D Manager
//
//  Created by Matthew Hutton on 16/03/2007.
//
//
//D&D Manager, a D&D Character and battle management program.
//Copyright (C) 2007, Matthew Hutton
//
//This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License along with this program; if not, write to:
//The Free Software Foundation, Inc.,
//51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#import "SpellMethods.h"
#import "RandomNumbers.h"
#import "FeatActions.h"
#import "AbilityChanged.h"

@implementation SpellMethods
+(int)averageSpellLevelForSpell:(NSManagedObject *)spell{
	//get the average level value.
	int j;
	int totalLevel=0;
	NSArray *array=[[spell valueForKey:@"spellClass"] allObjects];
	for(j=0;j<[array count];j++){
		totalLevel+=[[[array objectAtIndex:j] valueForKey:@"level"] intValue];
	}
	totalLevel+=j/2;//so it is at least approximately rounded up/down as required.
	return totalLevel/j;//now have an approximate value for the level.			
}
+(NSString *)processSpell:(NSManagedObject *)spell
				withFeats:(NSArray *)feats
				   forKey:(NSString *)key
				 forLevel:(int)level{
	double partsPerLvl=(double)[[spell valueForKey:[NSString stringWithFormat:@"%@PerLvls",key]] doubleValue];
	int startLevel=[[spell valueForKey:[NSString stringWithFormat:@"%@StartingAtLevel",key]] intValue];
	if(partsPerLvl==0){
		partsPerLvl=1;
	}
	//set start level to 1 as required.
	if(startLevel==0){
		startLevel=1;
		[spell setValue:[NSNumber numberWithInt:1]
				 forKey:[NSString stringWithFormat:@"%@StartingAtLevel",key]];
	}
	int theLevel=level-startLevel+1;
	//check for caster level feats.
	int i;
	for(i=0;i<[feats count];i++){
		NSManagedObject *feat=[feats objectAtIndex:i];
		if([[feat valueForKey:@"spellKey"] isEqualTo:@"Caster Level"]){
			NSString *mod=[feat valueForKey:@"spellMod"];
			if([mod isEqualToString:@"+x"]){
				theLevel=theLevel+[[feat valueForKey:@"xValue"] intValue];
			}else if([mod isEqualToString:@"Max"]){
			}else{
				theLevel=[FeatActions processValue:theLevel
										byModifier:[feat valueForKey:@"spellMod"]];
			}
		}
	}
	//NSLog(@"level=%d",theLevel);
	//NSLog(@"startLevel=%f",startLevel);
	//NSLog(@"parts per level=%f",partsPerLvl);
	//NSLog(@"key=%@",key);
	if(partsPerLvl==0.0){
		partsPerLvl=1.0;
	}
	double perLvl=((double)theLevel)/partsPerLvl;
	//NSLog(@"perLvl=%f",perLvl);
	perLvl=perLvl+0.9999;
	//NSLog(@".1");
	int sizeOfDie1=[[spell valueForKey:[NSString stringWithFormat:@"%@LvlSizeOfDie",key]] intValue];
	int sizeOfDie2=[[spell valueForKey:[NSString stringWithFormat:@"%@BonSizeOfDie",key]] intValue];
	//NSLog(@".2");
	//get the noOfDie/level.
	int noOfDie1=[[spell valueForKey:[NSString stringWithFormat:@"%@LvlNoOfDie",key]] intValue]*(int)perLvl;
	int maxValue=[[spell valueForKey:[NSString stringWithFormat:@"%@MaxNoOfDie",key]] intValue];
	if(noOfDie1>maxValue && maxValue!=0){
		noOfDie1=[[spell valueForKey:[NSString stringWithFormat:@"%@MaxNoOfDie",key]] intValue];
	}
	//NSLog(@".3");
	//get the bonus die.
	int noOfDie2=[[spell valueForKey:[NSString stringWithFormat:@"%@BonNoOfDie",key]] intValue];
	//get the bonus to the die.
	//NSLog(@".4");
	//NSLog(@"perLvl=%d, lvlBonus=%d",(int)perLvl,[[spell valueForKey:[NSString stringWithFormat:@"%@LvlBonus",key]] intValue]);
	int bonus=[[spell valueForKey:[NSString stringWithFormat:@"%@LvlBonus",key]] intValue]*(int)perLvl;
	maxValue=[[spell valueForKey:[NSString stringWithFormat:@"%@MaxBonus",key]] intValue];
	if(bonus>maxValue && maxValue!=0){
		bonus=[[spell valueForKey:[NSString stringWithFormat:@"%@MaxBonus",key]] intValue];
	}
	//if there is a maximise feat.
	if([FeatActions aMaxFeatSelectedForKey:key
								  forFeats:feats]){
		bonus=bonus+noOfDie1*sizeOfDie1+noOfDie2*sizeOfDie2;
		noOfDie1=0;
		sizeOfDie1=0;
		noOfDie2=0;
		sizeOfDie2=0;
	}
	//NSLog(@".5");
	//NSLog(@"bonus #1=%d",bonus);
	bonus=bonus+[[spell valueForKey:[NSString stringWithFormat:@"%@BonBonus",key]] intValue];
	//NSLog(@"bonus #2=%d",bonus);
	//now check feats for addition feats
	for(i=0;i<[feats count];i++){
		NSManagedObject *feat=[feats objectAtIndex:i];
		if([FeatActions checkIfFeat:feat
					   worksWithKey:key]){
			NSString *mod=[feat valueForKey:@"spellMod"];
			if([mod isEqualToString:@"+1"]){
				bonus=[FeatActions processValue:bonus
									 byModifier:mod];
			}else if([mod isEqualToString:@"+x"]){
				int m=[[feat valueForKey:@"xValue"] intValue];
				bonus=bonus+m;
			}
		}
	}
	//NSLog(@"bonus #3=%d",bonus);
	//check if the dice aren't the same size and one isn't zero.
	NSString *stringToReturn;
	if(sizeOfDie1 !=sizeOfDie2 && sizeOfDie1!= 0 && sizeOfDie2!= 0){
	//	//NSLog(@".6");
		if(bonus==0){//no bonus
			stringToReturn=[NSString stringWithFormat:@"%dd%d+%dd%d",noOfDie1,sizeOfDie1,noOfDie2,sizeOfDie2];
		}else{
			stringToReturn=[NSString stringWithFormat:@"%dd%d+%dd%d+%d",noOfDie1,sizeOfDie1,noOfDie2,sizeOfDie2,bonus];
		}
	}else if(noOfDie1==0 && noOfDie2==0){//no dice.
	//	//NSLog(@".61");
		if(bonus==0){
			stringToReturn=@"";
		}else{
	//		//NSLog(@".7");
			stringToReturn=[NSString stringWithFormat:@"%d",bonus];
		}
	}else{
	//	//NSLog(@".8");
		if(sizeOfDie1==0){
			sizeOfDie1=sizeOfDie2;
		}
		if(bonus==0){
			stringToReturn=[NSString stringWithFormat:@"%dd%d",noOfDie1+noOfDie2,sizeOfDie1];
		}else{
			stringToReturn=[NSString stringWithFormat:@"%dd%d+%d",noOfDie1+noOfDie2,sizeOfDie1,bonus];
		}		
	}
	//now check string for multiplier feats.
	for(i=0;i<[feats count];i++){
		NSManagedObject *feat=[feats objectAtIndex:i];
		if([[feat valueForKey:@"spellMod"] isEqualTo:@"Caster Level"]){
			NSString *mod=[feat valueForKey:@"spellMod"];
			if([mod hasSuffix:@"%%"]){
				stringToReturn=[FeatActions modifyString:stringToReturn
											byMultiplier:mod];
			}
			
		}
	}
	if([stringToReturn isEqualToString:@""]){
		stringToReturn=@"None";
	}
	//NSLog(@"string to return=%@",stringToReturn);
	return stringToReturn;
}
+(int)rollDiceForSpell:(NSManagedObject *)spell
			 withFeats:(NSArray *)feats
				forKey:(NSString *)key
			  forLevel:(int)level{
	if([key isEqualToString:@"dam"]){
		NSLog(@"caution when rolling damage dice should have a spell target to apply them to.");
		return [self rollDiceForSpell:spell
							withFeats:feats
							   forKey:key
							 forLevel:level
					   forSpellTarget:nil];
	}else{
		return [self rollDiceForSpell:spell
							withFeats:feats
							   forKey:key
							 forLevel:level
					   forSpellTarget:nil];
	}
	return 0;
}
+(int)rollDiceForSpell:(NSManagedObject *)spell
			 withFeats:(NSArray *)feats
				forKey:(NSString *)key
			  forLevel:(int)level
		forSpellTarget:(NSManagedObject *)spellTarget{
	double partsPerLvl=(double)[[spell valueForKey:[NSString stringWithFormat:@"%@PerLvls",key]] doubleValue];
	int startLevel=[[spell valueForKey:[NSString stringWithFormat:@"%@StartingAtLevel",key]] intValue];
	//set start level to 1 as required.
	if(startLevel==0){
		startLevel=1;
		[spell setValue:[NSNumber numberWithInt:1]
				 forKey:[NSString stringWithFormat:@"%@StartingAtLevel",key]];
	}
	//NSLog(@"startLevel=%f",startLevel);
	//NSLog(@"parts per level=%f",partsPerLvl);
	if(partsPerLvl==0.0){
		partsPerLvl=1.0;
	}
	int theLevel=level-startLevel+1;
	//check for caster level feats.
	int i;
	for(i=0;i<[feats count];i++){
		NSManagedObject *feat=[feats objectAtIndex:i];
		if([[feat valueForKey:@"spellKey"] isEqualTo:@"Caster Level"]){
			NSString *mod=[feat valueForKey:@"spellMod"];
			if([mod isEqualToString:@"+x"]){
				theLevel=theLevel+[[feat valueForKey:@"xValue"] intValue];
			}else if([mod isEqualToString:@"Max"]){
			}else{
				theLevel=[FeatActions processValue:theLevel
										byModifier:[feat valueForKey:@"spellMod"]];
			}
		}
	}
	double perLvl=((double)theLevel)/partsPerLvl;
	//NSLog(@"perLvl=%f",perLvl);
	perLvl=perLvl+0.9999;
	//NSLog(@"perLevel=%d",perLevel);
	//NSLog(@".1");
	int sizeOfDie1=[[spell valueForKey:[NSString stringWithFormat:@"%@LvlSizeOfDie",key]] intValue];
	//NSLog(@".2");
	//get the noOfDie/level.
	int noOfDie1=[[spell valueForKey:[NSString stringWithFormat:@"%@LvlNoOfDie",key]] intValue]*(int)perLvl;
	int maxValue=[[spell valueForKey:[NSString stringWithFormat:@"%@MaxNoOfDie",key]] intValue];
	if(noOfDie1>maxValue && maxValue!=0){
		noOfDie1=[[spell valueForKey:[NSString stringWithFormat:@"%@MaxNoOfDie",key]] intValue];
	}
	int total=0;
	for(i=0;i<noOfDie1;i++){
		total=total+[RandomNumbers randomIntUpTo:sizeOfDie1];
	}
	//NSLog(@".3");
	//get the bonus die.
	int sizeOfDie2=[[spell valueForKey:[NSString stringWithFormat:@"%@BonSizeOfDie",key]] intValue];
	int noOfDie2=[[spell valueForKey:[NSString stringWithFormat:@"%@BonNoOfDie",key]] intValue];
	for(i=0;i<noOfDie2;i++){
		total=total+[RandomNumbers randomIntUpTo:sizeOfDie2];
	}
	//if there is a maximise feat.
	if([FeatActions aMaxFeatSelectedForKey:key
								  forFeats:feats]){
		total=noOfDie1*sizeOfDie1+noOfDie2*sizeOfDie2;
		noOfDie1=0;
		sizeOfDie1=0;
		noOfDie2=0;
		sizeOfDie2=0;
	}
	//NSLog(@"perLvl=%d, lvlBonus=%d",(int)perLvl,[[spell valueForKey:[NSString stringWithFormat:@"%@LvlBonus",key]] intValue]);
	int bonus=[[spell valueForKey:[NSString stringWithFormat:@"%@LvlBonus",key]] intValue]*(int)perLvl;
	maxValue=[[spell valueForKey:[NSString stringWithFormat:@"%@MaxBonus",key]] intValue];
	if(bonus>maxValue && maxValue!=0){
		bonus=[[spell valueForKey:[NSString stringWithFormat:@"%@MaxBonus",key]] intValue];
	}
	//NSLog(@"bonus=%d",bonus);
	//NSLog(@".5");
	bonus=bonus+[[spell valueForKey:[NSString stringWithFormat:@"%@BonBonus",key]] intValue];
	if([key isEqualToString:@"dam"] && spellTarget!=nil){
		//check damage based on spellAffects/featFilter.
		if([[spell valueForKey:@"spellAffects"] intValue]>0){
			NSString *charType=[[spellTarget valueForKey:@"character"] valueForKey:@"type"];
			NSString *spellType=[spell valueForKey:@"featFilter"];
			BOOL matchesUp=NO;
			if([spellType hasSuffix:@"(All)"]){
				if([charType hasPrefix:[spellType substringToIndex:[spellType length]-6]]){
					matchesUp=YES;
				}
			}else{
				if([charType isEqualToString:spellType]){
					matchesUp=YES;
				}
			}
			if(matchesUp && [[spell valueForKey:@"spellAffects"] intValue]==1){
				//double damage.
				bonus=bonus*2;
				total=total*2;
			}else if(!matchesUp && [[spell valueForKey:@"spellAffects"] intValue]==2){
				//no damage caused as it doesn't match.
				bonus=0;
				total=0;
			}
		}
		[spellTarget setValue:[NSNumber numberWithInt:bonus]
					   forKey:@"bonusDamage"];
		[spellTarget setValue:[NSNumber numberWithInt:total]
					   forKey:@"diceDamage"];
		//NSLog(@"bonus=%d, dice=%d",bonus,total);
	}
	//NSLog(@"bonus=%d",bonus);
	total=total+bonus;
	//process total by feats.
	for(i=0;i<[feats count];i++){
		NSManagedObject *feat=[feats objectAtIndex:i];
		if([FeatActions checkIfFeat:feat
					   worksWithKey:key]){
			NSString *mod=[feat valueForKey:@"spellMod"];
			if([mod isEqualToString:@"+x"]){
				total=total+[[feat valueForKey:@"xValue"] intValue];
			}else if([mod isEqualToString:@"Max"]){
			}else{
				total=[FeatActions processValue:total
									 byModifier:[feat valueForKey:@"spellMod"]];
			}
		}
	}
	return total;
}
+(BOOL)rollASaveOfDC:(int)dc
			  ofType:(NSString *)type
				  on:(NSManagedObject *)target{
	int bonus;
	if([type isEqualToString:@"Fortitude"]){
		bonus=[[target valueForKey:@"fortitudeTotal"] intValue];
	}else if([type isEqualToString:@"Reflex"]){
		bonus=[[target valueForKey:@"reflexTotal"] intValue];
	}else if([type isEqualToString:@"Will"]){
		bonus=[[target valueForKey:@"willTotal"] intValue];
	}
	int dieRoll=[RandomNumbers randomIntUpTo:20];
	//NSLog(@"dieRoll=%d, bouns=%d",dieRoll,bonus);
	if(dieRoll==1){
		//fail
		return NO;
	}else if(dieRoll==20){
		return YES;
	}else{
		if(dieRoll+bonus>=dc){
			return YES;
		}else{
			return NO;
		}
	}
}
+(void)processRangeDescriptionForSpell:(NSManagedObject *)spell{
	
	//create description.
	NSString *str=@"";
	//check measurement unit.
	NSString *measuredIn;
	if([[spell valueForKey:@"ranMeasuredIn"] intValue]==0){
		measuredIn=@"feet";
	}else if([[spell valueForKey:@"ranMeasuredIn"] intValue]==1){
		measuredIn=@"miles";
	}
	//get dice per level
	if([[spell valueForKey:@"ranLvlNoOfDie"] intValue]!=0){
		if([spell valueForKey:@"ranLvlSizeOfDie"]==nil){
			[spell setValue:[NSNumber numberWithInt:1]
					 forKey:@"ranLvlSizeOfDie"];
		}
		str=[NSString stringWithFormat:@"%@d%@",[spell valueForKey:@"ranLvlNoOfDie"],[spell valueForKey:@"ranLvlSizeOfDie"]];
	}
	//get bonus per level.
	if([[spell valueForKey:@"ranLvlBonus"] intValue]!=0){
		if([str isEqualToString:@""]){
			str=[NSString stringWithFormat:@"%@",[spell valueForKey:@"ranLvlBonus"]];
		}else{
			str=[NSString stringWithFormat:@"%@+%@",str,[spell valueForKey:@"ranLvlBonus"]];
		}
	}
	//check if any content
	if(![str isEqualToString:@""]){
		//gets the rate of increase
		int noOfLvls=[[spell valueForKey:@"ranPerLvls"] intValue];
		if(noOfLvls==1){
			str=[NSString stringWithFormat:@"%@ %@/level ",str,measuredIn];
		}else{
			str=[NSString stringWithFormat:@"%@ %@/%d levels ",str,measuredIn,noOfLvls];
		}
		//try to get maximum.
		NSString *str2=@"";
		if([[spell valueForKey:@"ranMaxNoOfDie"] intValue]!=0){
			str2=[NSString stringWithFormat:@"%@d%@",[spell valueForKey:@"ranMaxNoOfDie"],[spell valueForKey:@"ranLvlSizeOfDie"]];
		}
		if([[spell valueForKey:@"ranMaxBonus"] intValue]!=0){
			if([str2 isEqualToString:@""]){
				str2=[NSString stringWithFormat:@"%@",[spell valueForKey:@"ranMaxBonus"]];
			}else{
				str2=[NSString stringWithFormat:@"%@+%@",str2,[spell valueForKey:@"ranMaxBonus"]];
			}
		}
		if(![str2 isEqualToString:@""]){
			str=[NSString stringWithFormat:@"%@(max. %@ %@) ",str,str2,measuredIn];
		}
		int startLevel=[[spell valueForKey:@"ranStartingAtLevel"] intValue];
		if(startLevel>1){
			str=[str stringByAppendingFormat:@"(from level %d) ",startLevel];
		}
	}
	//add on the fixed bonus.
	NSString *str2=@"";
	if([[spell valueForKey:@"ranBonNoOfDie"] intValue]!=0){
		if([spell valueForKey:@"ranBonSizeOfDie"]==nil){
			[spell setValue:[NSNumber numberWithInt:1]
					 forKey:@"ranBonSizeOfDie"];
		}
		str2=[NSString stringWithFormat:@"%@d%@ ",[spell valueForKey:@"ranBonNoOfDie"],[spell valueForKey:@"ranBonSizeOfDie"]];
	}
	if([[spell valueForKey:@"ranBonBonus"] intValue]!=0){
		if([str2 isEqualToString:@""]){
			str2=[NSString stringWithFormat:@"%@",[spell valueForKey:@"ranBonBonus"]];
		}else{
			str2=[NSString stringWithFormat:@"%@+%@",str2,[spell valueForKey:@"ranBonBonus"]];
		}
	}
	if(![str2 isEqualToString:@""]){
		if([str isEqualToString:@""]){
			str=[NSString stringWithFormat:@"%@ %@",str2,measuredIn];
		}else{
			str=[NSString stringWithFormat:@"%@ + %@ %@",str,str2,measuredIn];
		}
	}
	[spell setValue:str
			 forKey:@"ranDescription"];
}
+(void)processFeatDescriptionForSpell:(NSManagedObject *)spell{
	NSMutableString *desc=[NSMutableString stringWithCapacity:5];
	int i;
	for(i=1;i<5;i++){
		//check if there is a key first.
		NSString *key=[spell valueForKey:[NSString stringWithFormat:@"key%d",i]];
		if(![key isEqualToString:@"No Effect"] && ![key isEqualToString:@"No Skill Chosen"]){
			BOOL someMod=NO;
			/*if(![[spell valueForKey:[NSString stringWithFormat:@"dieMod%d",i]] isEqualToString:@"No die"]){
				[desc appendString:[spell valueForKey:[NSString stringWithFormat:@"dieMod%d",i]]];
				someMod=YES;
			}*/
			if(![[spell valueForKey:[NSString stringWithFormat:@"mod%d",i]] isEqualToString:@"+0"]){
				[desc appendString:[spell valueForKey:[NSString stringWithFormat:@"mod%d",i]]];
				someMod=YES;
			}
			if(!someMod){
				if([key isEqualToString:@"Hasted"] || [key isEqualToString:@"Slowed"]){
					[desc appendString:key];
					if(i!=4){
						[desc appendString:@"\n"];
					}
				}
				//no modifier.
				continue;
			}
			[desc appendString:@" to "];
			[desc appendString:key];
			if(i!=4){
				[desc appendString:@"\n"];
			}
		}
	}
	[spell setValue:desc
			 forKey:@"featDescription"];
}
+(NSManagedObject *)setupSpellClassForCharClass:(NSManagedObject *)charClass{
	NSManagedObjectContext *mObjC=[charClass managedObjectContext];
	NSManagedObjectModel *model=[[mObjC persistentStoreCoordinator] managedObjectModel];
	NSManagedObject *spellClass=[[NSManagedObject alloc] initWithEntity:[[model entitiesByName]  objectForKey:@"SpellClass"]
										 insertIntoManagedObjectContext:mObjC];
	if(charClass==nil){
		NSLog(@"error, nil object sent");
		return spellClass;
	}
	if([[charClass valueForKey:@"divineSpell"] intValue]==-1){
		[spellClass setValue:[NSNumber numberWithBool:YES]
					  forKey:@"domainSpell"];
	}else{
		[spellClass setValue:[NSNumber numberWithBool:NO]
					  forKey:@"domainSpell"];
	}
	[spellClass setValue:charClass
				  forKey:@"aClass"];
	[spellClass setValue:[charClass valueForKey:@"name"]
				  forKey:@"name"];
	return spellClass;	
}
/*!
 * Checks if character should have spell level stuff setup automatically, and then sets it up, processes the character class too to set it up originally if required, if no non-blank value is found nothing is set.
 * \param characterClass the character class in question
 * \param spellLevel the spell level being updated.
 * \param casterLevel the caster level of the character.
 */
+(void)setupBaseAvailableSpellsForCC:(NSManagedObject *)characterClass
					   forSpellLevel:(NSManagedObject *)spellLevel
					   atCasterLevel:(int)casterLevel{
	NSArray *globalSpells=[[[characterClass valueForKey:@"globalSpellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"level==%d",[[spellLevel valueForKey:@"level"] intValue]]];
	if([globalSpells count]==0){
		//check if processed first.
		[AbilityChanged setupGlobalSpellLevelsForCharacterClass:characterClass];
		globalSpells=[[[characterClass valueForKey:@"globalSpellLevel"] allObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"level==%d",[[spellLevel valueForKey:@"level"] intValue]]];
		if([globalSpells count]==0){
			NSLog(@"error, no spell level found");
			return;
		}
	}
	if(![[[spellLevel valueForKey:@"character"] valueForKey:@"classControlsBaseAttackAndSaves"] boolValue]){
		return;
	}
	NSManagedObject *globalSpell=[globalSpells objectAtIndex:0];
	//spells per day.
	int maxValue=-1;
	int i;
	for(i=0;i<7;i++){
		NSNumber *num=[globalSpell valueForKey:[NSString stringWithFormat:@"spd%d",i]];
		if(num==nil){
			continue;
		}
		int currentLevel=[num intValue];
		if(currentLevel<=casterLevel){
			maxValue=i;
		}
	}
	if(maxValue==-1){
		[spellLevel setValue:nil
					  forKey:@"baseSpells"];
		[spellLevel setValue:nil
					  forKey:@"totalSpells"];
		[spellLevel setValue:nil
					  forKey:@"spellsLeft"];
	}else{
		[spellLevel setValue:[NSNumber numberWithInt:maxValue]
					  forKey:@"baseSpells"];
		int ts=maxValue+[[spellLevel valueForKey:@"miscBonusSpells"] intValue]+[[spellLevel valueForKey:@"abilityBonusSpells"] intValue];
		[spellLevel setValue:[NSNumber numberWithInt:ts]
					  forKey:@"totalSpells"];
		[spellLevel setValue:[NSNumber numberWithInt:ts-[[spellLevel valueForKey:@"spellsCast"] intValue]]
					  forKey:@"spellsLeft"];
	}
	//exits if not spontaneous spells.
	if(![[characterClass valueForKey:@"allSpontaneous"] boolValue]){
		return;
	}
	//total spells
	maxValue=-1;
	for(i=1;i<10;i++){
		NSNumber *num=[globalSpell valueForKey:[NSString stringWithFormat:@"ts%d",i]];
		if(num==nil){
			continue;
		}
		int currentLevel=[num intValue];
		if(currentLevel<=casterLevel){
			maxValue=i;
		}
	}
	if(maxValue==-1){
		[spellLevel setValue:nil
					  forKey:@"baseAvailableSpells"];
		[spellLevel setValue:nil
					  forKey:@"totalAvailableSpells"];
	}else{
		[spellLevel setValue:[NSNumber numberWithInt:maxValue]
					  forKey:@"baseAvailableSpells"];
		[spellLevel setValue:[NSNumber numberWithInt:maxValue+[[spellLevel valueForKey:@"miscAvailableSpells"] intValue]]
					  forKey:@"totalAvailableSpells"];
	}
}
@end
